package com.xxmw.transaction.controller.robot;

import com.xxmw.transaction.common.entity.P;
import com.xxmw.transaction.common.entity.R;
import com.xxmw.transaction.common.utils.Constant;
import com.xxmw.transaction.controller.BaseController;
import com.xxmw.transaction.model.ScheduleJob;
import com.xxmw.transaction.model.app.BourseApi;
import com.xxmw.transaction.model.robot.RobotStrategy;
import com.xxmw.transaction.model.subscribe.SymbolSub;
import com.xxmw.transaction.service.app.BourseApiService;
import com.xxmw.transaction.service.app.SymbolSubService;
import com.xxmw.transaction.service.robot.RobotStrategyService;
import com.xxmw.transaction.service.job.ScheduleJobService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * 机器人挂单控制器
 * @author luowenliang
 * @since 2020/2/18 17:27
 */
@Validated
@RestController
@RequestMapping("/admin/robot/job")
public class RobotJobController extends BaseController {

    private static final String PER_SECOND_CRON = "*/%s * * * * ?";

    private static final String ROBOT_ORDER_BEAN_NAME = "robotOrderTask";

    private static final String ROBOT_ORDER_METHOD_NAME = "place";

    @Autowired
    private BourseApiService bourseApiService;

    @Autowired
    private ScheduleJobService scheduleJobService;

    @Autowired
    private RobotStrategyService robotStrategyService;

    @Autowired
    private SymbolSubService symbolSubService;

    /**
     * 机器人任务列表获取
     * 共用
     * @param pageNum
     * @param pageSize
     * @param bourse
     * @return
     */
    @GetMapping("/list")
    @RequiresPermissions("robot:job:list")
    public R list(@RequestParam(value = "pageNum", defaultValue = "1")Integer pageNum,
                  @RequestParam(value = "pageSize", defaultValue = "20")Integer pageSize,
                  @RequestParam(value = "bourse", required = false)Integer bourse) {
        P<ScheduleJob> p = scheduleJobService.getJobList(pageNum, pageSize, ScheduleJob.JobType.ROBOT.getValue(), bourse, null);
        return R.ok(p);
    }

    /**
     * 机器人挂单任务配置
     * 均为限价单
     * 价钱自己控制 挂单数量最小
     * 不能卖出 不能买进 只刷交易量
     * @param bourse 交易所
     * @param symbol 交易对 btcusdt
     * @param second 挂单频率 1s-5s
     * @return
     */
    @PostMapping("/save")
    @RequiresPermissions("robot:job:save")
    public R save ( @NotNull(message = "请选择交易所") @RequestParam(value = "bourse") Integer bourse,
                    @RequestParam(value = "symbol") String symbol,
                    @Min(value = 1, message = "频率必须大于0") @Max(value = 15, message = "频率不能超过15") @RequestParam(value = "second") Integer second) {
        RobotStrategy robotStrategy = robotStrategyService.getByBourseAndSymbol(bourse, symbol);
        if (null == robotStrategy) {
            return R.error("请先配置该币种机器人策略");
        }
        SymbolSub symbolSub = symbolSubService.getByBourseAndSymbol(bourse, symbol);
        if (null == symbolSub) {
            return R.error("请先订阅该交易所的交易对");
        }

        BourseApi bourseApi = bourseApiService.getById(bourse);
        if (null == bourseApi) {
            return R.error("请先配置交易所API");
        }
        ScheduleJob oldJob = scheduleJobService.getByBourseAndSymbol(bourse, symbol);
        if (null != oldJob) {
            return R.error("已有该任务配置，请勿重复配置");
        }
        oldJob = new ScheduleJob();
        oldJob.setStatus(Constant.ScheduleStatus.PAUSE.getValue());
        oldJob.setCreated(new Date());
        oldJob.setSymbol(symbol);
        oldJob.setBourse(bourse);
        oldJob.setType(ScheduleJob.JobType.ROBOT.getValue());
        oldJob.setRemark("机器人挂单任务");
        //交易所 + 交易对
        oldJob.setParams(bourse + "," + symbol);
        oldJob.setBeanName(ROBOT_ORDER_BEAN_NAME);
        oldJob.setMethodName(ROBOT_ORDER_METHOD_NAME);
        //*/5 * * * * ?
        oldJob.setCron(String.format(PER_SECOND_CRON, second));
        scheduleJobService.addOrUpdate(oldJob);
        return R.ok();
    }

    /**
     * 修改
     * @param second
     * @return
     */
    @PostMapping("/update")
    @RequiresPermissions("robot:job:save")
    public R update (@RequestParam("id") Long id,
                     @Min(value = 1, message = "频率必须大于0") @Max(value = 15, message = "频率不能超过15") @RequestParam(value = "second") Integer second) {
        ScheduleJob job = scheduleJobService.getById(id);
        if (null == job) {
            return R.error("该任务不存在");
        }
        job.setCron(String.format(PER_SECOND_CRON, second));
        scheduleJobService.addOrUpdate(job);
        return R.ok();
    }
}
